package linker.plugin;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import com.google.gdata.client.calendar.CalendarQuery;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.data.calendar.WebContent;
import com.google.gdata.data.extensions.When;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

/**
 * 
 * @author Jianfeng jianfeng.linker@gmail.com
 * 
 */
public class GCalendar extends PluginItem implements ActionListener {
	// @_@
	private static final long serialVersionUID = 1L;

	// The base URL for a user's calendar metafeed (needs a username appended).
	private static final String METAFEED_URL_BASE = "http://www.google.com/calendar/feeds/";

	// The string to add to the user's metafeedUrl to access the event feed for
	// their primary calendar.
	private static final String EVENT_FEED_URL_SUFFIX = "/private/full";

	// The URL for the event feed of the specified user's primary calendar.
	// (e.g. http://www.googe.com/feeds/calendar/jdoe@gmail.com/private/full)
	private static URL eventFeedUrl = null;

	private JButton refreshButton = new JButton("Refresh");

	private JButton addButton = new JButton("Add");

	private String userName = null;

	private String password = null;

	private DefaultTableModel tableModel = new DefaultTableModel();

	private CalendarService myService;

	public GCalendar() {
		super("Google calendar");
		setName("GCalendar");
	}

	public void setPluginDir(String dir) {
		icon = new ImageIcon(dir + fileSeparator + "icon.png");
		create();

	}

	public void create() {
		Container container = getContentPane();

		JPanel userPanel = new JPanel();
		addButton.addActionListener(this);
		userPanel.add(addButton);
		refreshButton.addActionListener(this);
		userPanel.add(refreshButton);
		container.add(userPanel, BorderLayout.NORTH);

		JTable eventTable = new JTable();
		tableModel.addColumn("Title");
		tableModel.addColumn("Time");
		eventTable.setModel(tableModel);
		eventTable.setCellSelectionEnabled(false);
		eventTable.setColumnSelectionAllowed(false);
		eventTable.setRowSelectionAllowed(true);
		container.add(new JScrollPane(eventTable), BorderLayout.CENTER);

		setWindow();
	}

	public void setAccount(String userName, String password) {
		this.userName = userName;
		this.password = password;

		initial();
	}

	private void initial() {
		try {
			eventFeedUrl = new URL(METAFEED_URL_BASE + userName
					+ EVENT_FEED_URL_SUFFIX);

			myService = new CalendarService("LinkerForGCalendar");
			myService.setUserCredentials(userName, password);

		} catch (AuthenticationException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void refresh() {

		for (int i = tableModel.getRowCount() - 1; i >= 0; i--)
			tableModel.removeRow(i);

		CalendarQuery query = new CalendarQuery(eventFeedUrl);

		query.setMinimumStartTime(DateTime.now());
		CalendarEventFeed feed;
		try {
			feed = myService.getFeed(query, CalendarEventFeed.class);

			List<CalendarEventEntry> entries = feed.getEntries();

			for (int i = 0; i < entries.size(); i++) {
				Vector<String> v = new Vector<String>();
				v.add(entries.get(i).getTitle().getPlainText());
				v.add(entries.get(i).getTimes().get(0).getStartTime()
						.toString());
				tableModel.addRow(v);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ServiceException e) {
			e.printStackTrace();
		}

	}

	public static void main(String args[]) {
		GCalendar calendar = new GCalendar();
		calendar.create();
		calendar.setVisible(true);
	}

	private static CalendarEventEntry createEvent(CalendarService service,
			String eventTitle, String eventContent, When time,
			boolean isQuickAdd, WebContent wc) throws ServiceException,
			IOException {
		CalendarEventEntry myEntry = new CalendarEventEntry();

		myEntry.setTitle(new PlainTextConstruct(eventTitle));
		myEntry.setContent(new PlainTextConstruct(eventContent));
		myEntry.setQuickAdd(isQuickAdd);
		myEntry.setWebContent(wc);

		// If a recurrence was requested, add it. Otherwise, set the
		// time (the current date and time) and duration (30 minutes)
		// of the event.
		if (time == null) {
			Calendar calendar = new GregorianCalendar();
			DateTime startTime = new DateTime(calendar.getTime(), TimeZone
					.getDefault());

			calendar.add(Calendar.MINUTE, 60);
			DateTime endTime = new DateTime(calendar.getTime(), TimeZone
					.getDefault());

			time = new When();
			time.setStartTime(startTime);
			time.setEndTime(endTime);
		}

		myEntry.addTime(time);

		return service.insert(eventFeedUrl, myEntry);
	}

	public void actionPerformed(ActionEvent e) {
		getUserAccount();

		if (e.getSource() == refreshButton) {
		} else if (e.getSource() == addButton) {
			String eventTitle = JOptionPane.showInputDialog("Input eventTitle");
			String eventContent = JOptionPane
					.showInputDialog("Input eventContent");
			try {
				createEvent(myService, eventTitle, eventContent, null, false,
						null);
			} catch (ServiceException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}

		refresh();
	}

	private void getUserAccount() {
		if (userName == null || password == null) {
			userName = JOptionPane.showInputDialog("Input user name");
			password = JOptionPane.showInputDialog("Input password");

			initial();
		}
	}

	public String toString() {
		return "GCalendar";
	}

}
